Skip to content

feat(sdk-coin-starknet): implement Starknet SDK module#8781

Draft
shubham-damkondwar wants to merge 2 commits into
feat/starknet/pr1-staticsfrom
feat/starknet/pr2-sdk-module
Draft

feat(sdk-coin-starknet): implement Starknet SDK module#8781
shubham-damkondwar wants to merge 2 commits into
feat/starknet/pr1-staticsfrom
feat/starknet/pr2-sdk-module

Conversation

@shubham-damkondwar
Copy link
Copy Markdown
Contributor

Summary

  • Implements modules/sdk-coin-starknet — full unique chain SDK package
  • Coin class, transaction builders, key pair, utils, and full test suite
  • 45 unit tests passing

Chain Type

ECDSA (secp256k1) — uses OZ EthAccountUpgradeable for account abstraction on Starknet L2

MPC Support

  • secp256k1 ECDSA TSS (same as ICP)
  • shouldHash=false (Poseidon pre-hashed transactions)
  • Signature format: [r_low, r_high, s_low, s_high, v]

Reference Implementations

  • ICP (coin class skeleton, ECDSA key pair, MPC patterns)
  • strkMPC sandbox (transaction building, address derivation, signature formatting)

Changes

  • src/starknet.ts + tstarknet.ts — mainnet + testnet coin classes
  • src/lib/transactionBuilderFactory.ts — builder factory
  • src/lib/transferBuilder.ts — STRK transfer transactions (ERC-20 calldata)
  • src/lib/keyPair.ts — secp256k1 key pair with Starknet address derivation
  • src/lib/transaction.ts — transaction parse/explain/serialize
  • src/lib/utils.ts — address validation, EthAccount address computation, signature formatting
  • src/lib/iface.ts, constants.ts — types and chain constants
  • test/unit/ — keyPair, transaction, builder, coin, and utils tests

Related

🤖 Generated with Claude Code

shubham-damkondwar and others added 2 commits May 15, 2026 19:51
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comment on lines +1 to +18
export const DECIMALS = 18;

// OZ EthAccountUpgradeable class hash (v0.17.0) — secp256k1 signature verification
export const OZ_ETH_ACCOUNT_CLASS_HASH = '0x3940bc18abf1df6bc540cabadb1cad9486c6803b95801e57b6153ae21abfe06';

// STRK token contract (same on both mainnet and sepolia)
export const STRK_TOKEN_CONTRACT = '0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d';

// ETH token contract on Starknet
export const ETH_TOKEN_CONTRACT = '0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7';

// Chain IDs
export const MAINNET_CHAIN_ID = '0x534e5f4d41494e'; // SN_MAIN
export const TESTNET_CHAIN_ID = '0x534e5f5345504f4c4941'; // SN_SEPOLIA

// RPC endpoints
export const MAINNET_RPC_URL = 'https://starknet-mainnet-rpc.publicnode.com/';
export const TESTNET_RPC_URL = 'https://starknet-sepolia-rpc.publicnode.com/';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these should be declared in modules/statics/src/networks.ts and used form there

export interface StarknetTransactionData {
senderAddress: string;
calls: StarknetCall[];
nonce?: string;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should nonce be optional ? as far as i remember nonce is serving the same purpose as evm nonce

Comment on lines +31 to +36
signature?: string[];
transactionHash?: string;
// For token transfers
receiverAddress?: string;
amount?: string;
tokenContract?: string;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check for these optional fields as well
i feel like amount should not just be for token transfer and mandotory field

Comment on lines +40 to +47
id?: string;
sender: string;
senderPublicKey?: string;
recipient?: string;
amount?: string;
fee?: string;
nonce?: string;
type?: BitGoTransactionType;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same check for optional fields

import { bip32 } from '@bitgo/secp256k1';
import { randomBytes } from 'crypto';

const DEFAULT_SEED_SIZE_BYTES = 16;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move to constants file

Comment on lines +25 to +35
if (!address || !utils.isValidAddress(address)) {
throw new BuildTransactionError('Invalid or missing address, got: ' + address);
}
if (pubKey && !utils.isValidPublicKey(pubKey)) {
throw new BuildTransactionError('Invalid pubKey, got: ' + pubKey);
}
this._sender = address;
if (pubKey) {
this._publicKey = pubKey;
}
return this;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should have a check here that the address is corresponding to the public key

Comment on lines +65 to +71
public tokenContract(address: string): this {
if (!utils.isValidAddress(address)) {
throw new BuildTransactionError('Invalid token contract address');
}
this._tokenContract = address;
return this;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i guess the tokenContract is something we have in our system. in the network.ts file

Comment on lines +113 to +115
validateTransaction(_transaction: Transaction): void {
// Subclasses provide specific validation
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

either implement the function or return not implemented error

protected async buildImplementation(): Promise<Transaction> {
this.validateTransfer();

const tokenContract = this._tokenContract || STRK_TOKEN_CONTRACT;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think we should keep the _tokenContract fix and fetch from network.ts rather than letting the caller set it

Comment on lines +155 to +158
protected signImplementation(key: BaseKey): Transaction {
this.validateKey(key);
return this._transaction;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should function implement the signing logic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants